package net.mingsoft.document.biz.impl;

import net.mingsoft.basic.util.DateUtil;
import net.mingsoft.dashboard.action.q.dashboard.OperateQuery;
import net.mingsoft.dashboard.action.r.FileLogStatisticsResponse;
import net.mingsoft.document.action.r.statistic.FileStatisticResponse;
import net.mingsoft.document.biz.FileStatisticsBiz;
import net.mingsoft.document.constant.FileConstant;
import net.mingsoft.document.dao.FileDao;
import net.mingsoft.document.dao.FileLogDao;
import net.mingsoft.document.enums.FileOperateType;
import net.mingsoft.document.util.FileTypeUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.joda.time.Interval;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author gengfa
 * @date 22/02/08
 */
@Service
public class FileStatisticsBizImpl implements FileStatisticsBiz {
    @Resource
    FileDao fileDao;

    @Resource
    FileLogDao fileLogDao;

    @Override
    public List<FileStatisticResponse> fileCountGroupByType() {

        List<FileStatisticResponse> responses = fileDao.countFileGroupByType();
        List<FileStatisticResponse> resp = new ArrayList<>();

        FileStatisticResponse imageCount = new FileStatisticResponse().setName(FileConstant.IMAGE_NAME).setCount(0);
        FileStatisticResponse wordCount  = new FileStatisticResponse().setName(FileConstant.WORD_NAME).setCount(0);
        FileStatisticResponse excelCount = new FileStatisticResponse().setName(FileConstant.EXCEL_NAME).setCount(0);
        FileStatisticResponse pdfCount   = new FileStatisticResponse().setName(FileConstant.PDF_NAME).setCount(0);
        FileStatisticResponse pptCount   = new FileStatisticResponse().setName(FileConstant.PPT_NAME).setCount(0);
        FileStatisticResponse otherCount   = new FileStatisticResponse().setName(FileConstant.OTHER_NAME).setCount(0);

        resp.add(imageCount);
        resp.add(wordCount);
        resp.add(excelCount);
        resp.add(pdfCount);
        resp.add(pptCount);
        resp.add(otherCount);

        if (CollectionUtils.isNotEmpty(responses)) {
            for (FileStatisticResponse res : responses) {
                if (FileTypeUtil.isImage(res.getName())) {
                    imageCount.setCount(res.getCount()+imageCount.getCount());
                } else if (FileTypeUtil.isWord(res.getName())) {
                    wordCount.setCount(res.getCount()+wordCount.getCount());
                } else if (FileTypeUtil.isExcel(res.getName())) {
                    excelCount.setCount(res.getCount()+excelCount.getCount());
                } else if (FileTypeUtil.isPpt(res.getName())) {
                    pptCount.setCount(res.getCount()+pptCount.getCount());
                } else if (FileTypeUtil.isPdf(res.getName())) {
                    pdfCount.setCount(res.getCount()+pdfCount.getCount());
                } else {
                    otherCount.setCount(res.getCount()+otherCount.getCount());
                }
            }
        }

        return resp;
    }

    @Override
    public FileLogStatisticsResponse fileLogCountGroupByType(OperateQuery query) {

        FileLogStatisticsResponse response = new FileLogStatisticsResponse();
        response.setView(new ArrayList<>())
                .setDownload(new ArrayList<>())
                .setShare(new ArrayList<>())
                .setDelete(new ArrayList<>());

        if (StringUtils.equals(query.getType(), "TODAY")) {
            response = makeFileLogResponse(DateUtil.todayBegin(), DateUtil.todayEnd(), 3);
        } else if (StringUtils.equals(query.getType(), "YESTERDAY")) {
            response = makeFileLogResponse(DateUtil.lastNDay(1), DateUtil.todayBegin(), 3);
        } else if (StringUtils.equals(query.getType(), "LAST3")) {
            response = makeFileLogResponse(DateUtil.lastNDay(2), DateUtil.todayEnd(), 9);
        } else if (StringUtils.equals(query.getType(), "LAST7")) {
            response = makeFileLogResponseDay(DateUtil.lastNDay(6), DateUtil.todayEnd());
        } else {
            response = makeFileLogResponseDay(query.getBeginDate(), query.getEndDate());
        }

        return response;
    }

    public List<FileStatisticResponse> makeResponseList(String beginDate, String endDate, FileOperateType type, int n) {
        List<FileStatisticResponse> response = new ArrayList<>();
        List<String> dates = dateTimeList(beginDate, endDate, n);
        dates.forEach(it -> response.add(new FileStatisticResponse().setName(it).setCount(0)));

        List<FileStatisticResponse> req = fileLogDao.countFileLogGroupByOpType(beginDate, endDate, type.getType(), n);
        if (CollectionUtils.isNotEmpty(req)) {
            for (FileStatisticResponse v : req) {
                final int dateTimeSeg = getDateTimeSeg(dates, v.getName());
                response.get(dateTimeSeg).setCount(response.get(dateTimeSeg).getCount() + v.getCount());
            }
        }

        return response;
    }

    public int getDateTimeSeg(List<String> dates, String date) {
        for (int i = 0; i < dates.size(); i++) {
            if (DateUtil.toJodaDateTime(dates.get(i)).isAfter(DateUtil.toJodaDateTime(date))) {
                return i;
            }
        }
        return 0;
    }

    public List<String> dateTimeList(String beginDate, String endDate, int n) {
        List<String> dates = new ArrayList<>();
        DateTime begin = DateUtil.toJodaDateTime(beginDate);
        dates.add(beginDate);
        for (int i=0; i < 8; i++) {
            begin = begin.plusHours(n);
            dates.add(begin.toString(DateUtil.DATETIME_FORMAT_STR));
        }
        return dates;
    }

    public FileLogStatisticsResponse makeFileLogResponse(String beginDate, String endDate, int n) {
        List<FileStatisticResponse> view = makeResponseList(beginDate, endDate, FileOperateType.VIEW, n);
        List<FileStatisticResponse> share = makeResponseList(beginDate, endDate, FileOperateType.SHARE, n);
        List<FileStatisticResponse> download = makeResponseList(beginDate, endDate, FileOperateType.DOWNLOAD, n);
        List<FileStatisticResponse> delete = makeResponseList(beginDate, endDate, FileOperateType.DELETE, n);
        return new FileLogStatisticsResponse().setView(view).setShare(share).setDownload(download).setDelete(delete);
    }

    public List<FileStatisticResponse> makeDayResponseList(String beginDate, String endDate, FileOperateType type) {
        List<FileStatisticResponse> responses = new ArrayList<>();
        List<String> dates = dateList(beginDate, endDate);
        dates.forEach(it -> responses.add(new FileStatisticResponse().setName(it).setCount(0)));
        List<FileStatisticResponse> req = fileLogDao.countFileLogGroupByOpTypePerDay(beginDate, endDate, type.getType());
        if (CollectionUtils.isNotEmpty(req)) {
            for (FileStatisticResponse v : req) {
                final int dateSeg = getDateSeg(dates, v.getName());
                responses.get(dateSeg).setCount(responses.get(dateSeg).getCount() + v.getCount());
            }
        }
        return responses;
    }

    public int getDateSeg(List<String> dates, String date) {
        int index = -1;
        for (int i = 0; i < dates.size(); i++) {
            if (DateUtil.toJodaDateTimeR(dates.get(i)).isAfter(DateUtil.toJodaDateTimeR(date))) {
                index = i;
            }
        }
        if (index == -1) {
            return dates.size() - 1;
        }
        return index;
    }

    public List<String> dateList(String beginDate, String endDate) {
        List<String> dates = new ArrayList<>();
        DateTime begin = DateUtil.toJodaDateTime(beginDate);
        DateTime end = DateUtil.toJodaDateTime(endDate);
        long days = (end.getMillis() - begin.getMillis()) / (1000 * 3600 * 24);
        dates.add(begin.toString(DateUtil.DATE_FORMAT_STR));
        for (int i=0; i < days; i++) {
            begin = begin.plusDays(1);
            dates.add(begin.toString(DateUtil.DATE_FORMAT_STR));
        }
        return dates;
    }

    public FileLogStatisticsResponse makeFileLogResponseDay(String beginDate, String endDate) {
        List<FileStatisticResponse> view = makeDayResponseList(beginDate, endDate, FileOperateType.VIEW);
        List<FileStatisticResponse> share = makeDayResponseList(beginDate, endDate, FileOperateType.SHARE);
        List<FileStatisticResponse> download = makeDayResponseList(beginDate, endDate, FileOperateType.DOWNLOAD);
        List<FileStatisticResponse> delete = makeDayResponseList(beginDate, endDate, FileOperateType.DELETE);
        return new FileLogStatisticsResponse().setView(view).setShare(share).setDownload(download).setDelete(delete);
    }

}
